package com.springboot.nacos.config.client;

import small.common.core.constants.CommonConstants;
import org.springframework.core.env.MapPropertySource;
import org.springframework.core.env.PropertySource;
import org.springframework.util.CollectionUtils;

import java.util.*;

public class NacosPropertySource extends MapPropertySource {

    /**
     * Nacos Group.
     */
    private final String group;

    /**
     * Nacos dataID.
     */
    private final String dataId;

    /**
     * timestamp the property get.
     */
    private final Date timestamp;

    /**
     * Whether to support dynamic refresh for this Property Source.
     */
    private final boolean isRefreshable;

    NacosPropertySource(String group, String dataId, Map<String, Object> source,
                        Date timestamp, boolean isRefreshable) {
        super(String.join(CommonConstants.COMMAS, dataId, group), source);
        this.group = group;
        this.dataId = dataId;
        this.timestamp = timestamp;
        this.isRefreshable = isRefreshable;
    }

    public NacosPropertySource(List<PropertySource<?>> propertySources, String group,
                               String dataId, Date timestamp, boolean isRefreshable) {
        this(group, dataId, getSourceMap(group, dataId, propertySources), timestamp,
                isRefreshable);
    }

    /**
     * 转换为map
     *
     * @param group
     * @param dataId
     * @param propertySources
     * @return
     */
    private static Map<String, Object> getSourceMap(String group, String dataId,
                                                    List<PropertySource<?>> propertySources) {
        if (CollectionUtils.isEmpty(propertySources)) {
            return Collections.emptyMap();
        }
        if (propertySources.size() == 1) {
            PropertySource propertySource = propertySources.get(0);
            if (propertySource != null && propertySource.getSource() instanceof Map) {
                return (Map<String, Object>) propertySource.getSource();
            }
        }

        Map<String, Object> sourceMap = new LinkedHashMap<>();
        List<PropertySource<?>> otherTypePropertySources = new ArrayList<>();
        for (PropertySource<?> propertySource : propertySources) {
            if (propertySource == null) {
                continue;
            }
            //如果是map资源放入资源池，其他单独处理
            if (propertySource instanceof MapPropertySource) {
                MapPropertySource mapPropertySource = (MapPropertySource) propertySource;
                Map<String, Object> source = mapPropertySource.getSource();
                sourceMap.putAll(source);
            } else {
                otherTypePropertySources.add(propertySource);
            }
        }

        if (!otherTypePropertySources.isEmpty()) {
            sourceMap.put(String.join(CommonConstants.COMMAS, dataId, group),
                    otherTypePropertySources);
        }
        return sourceMap;
    }

    public boolean isRefreshable() {
        return isRefreshable;
    }

    public String getGroup() {
        return group;
    }

    public String getDataId() {
        return dataId;
    }

    public Date getTimestamp() {
        return timestamp;
    }
}
